#!/bin/bash
TOP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../.." &> /dev/null && pwd )"
CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

check_version_ge() {
    test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"
}
bash_xc='bash -xc'
# 检查是否有curl和wget
HAS_CURL="$(command -v curl >/dev/null 2>&1 && echo true || echo false)"
HAS_WGET="$(command -v wget >/dev/null 2>&1 && echo true || echo false)"

#usage: download_url <url> [target] 
download_url() {
  local target
  local url=$1
  local remote_file=""
  
  if [ $# -eq 2 ]; then
    target=$2
  elif [ $# -eq 1 ]; then 
    target=${1##*/}
  else
    echo "cmd err, usage: download_url <url> [target]"
    return 1
  fi
  if [ ! -f "$target" ] || ${FORCE} ; then
    if $HAS_CURL; then
      $bash_xc "curl -fsSL $url -o $target"
      if [ $? -ne 0 ]; then
	      echo "curl or wget failed"
        return 3
      fi
    elif $HAS_WGET; then
      $bash_xc "wget -q $url -O $target"
      if [ $? -ne 0 ]; then
	      echo "curl or wget failed"
        return 3
      fi
    fi
    echo "get $(basename $target) successfully"
    return 0
  else
    echo "do not get $(basename $url): file exist or force=${FORCE} "
    return 0
  fi
  return 0
}

download_url_until_succeed() {
  local target
  local url=$1
  
  if [ $# -eq 2 ]; then
    target=$2
  elif [ $# -eq 1 ]; then 
    target=${1##*/}
  else
    echo "cmd err, usage: download_url <url> [target]"
    return 1
  fi
  echo "download $url $target"
  
  while ! download_url $url $target; do
    sleep 5
  done
}


ARCH=$([ "x86_64" == $(uname -m) ] && echo "amd64")
#TARGET_VERSION是可变的，，使用方法，在TARGET_VERSION确定后，执行BINARY_URL_PATH=$(eval echo $BINARY_URL_PATH)
#例如，./install.sh --version=1.21.11, 则url=https://dl.k8s.io/release/v1.21.11/bin/linux/${ARCH}
#注意这个"\", #注意这个"\",#注意这个"\",
GH_PROXY=${URL_githubProxy:-https://ghproxy.com/}
BINARY_URL=${GH_PROXY}${DL_yq_bin:-"https://github.com/mikefarah/yq/releases/download/v\${TARGET_VERSION}/yq_linux_${ARCH}"}
DOWNLOAD_DIR=$CUR_DIR/package
DEFAULT_VERSION=4.33.3
BIN_DIR=/usr/local/bin

# Check if yq components are installed and if they need to be upgraded
yq_needs_installation() {
    if [ -x "$(command -v yq)" ]; then
        CURRENT_VERSION=$(yq --version | awk '{print $4}' | sed 's/^v//')
        #echo "Current version: $current_version, target version: $TARGET_VERSION"
        if [ -z "$TARGET_VERSION" ] && [ "$FORCE" = "false" ]; then
            echo "Current version is $CURRENT_VERSION, use '--force=true' or '--verion=<version> to install as desired"
			      return 1
        elif check_version_ge "$CURRENT_VERSION" "$TARGET_VERSION" && [ "$FORCE" != "true" ]; then
            echo "Current version ($CURRENT_VERSION) >= target version($TARGET_VERSION), and force=$FORCE; no need to install"
            return 1
        fi
    fi
    return 0
}
# Remove all Docker related files and services
# 删除docker所有的文件
remove_yq() {
    bash -xc "rm -rf $BIN_DIR/yq"
}
# deletes the old version of yq components.
# 删除旧版本的 yq 组件。
delete_old_version() {
    if [ -z "$CURRENT_VERSION" ]; then
        if [ -x "$(command -v yq)" ]; then
            CURRENT_VERSION=$(yq --version | awk '{print $4}')
        else
            echo "yq are not installed"
            #return
        fi
    fi
    echo "Delete version $CURRENT_VERSION ..."

    remove_yq
}


install_yq() {
    if [ ! -d $TARGET_BIN ]; then
        download_pkg
    fi
    set -x
    cp -rf $TARGET_BIN $BIN_DIR/yq
    chmod +x $BIN_DIR/yq
    set +x
    yq --version
}
download_pkg() {
    mkdir -p $DOWNLOAD_DIR
    download_url_until_succeed  $BINARY_URL $TARGET_BIN
}

clean_download() {
    [ "$DOWNLOAD_DIR" != "$CUR_DIR" ] && bash -xc "rm -rf $DOWNLOAD_DIR"
}

function print_usage() {
    echo "Usage: $0 [OPTIONS]"
    echo "Options:"
    echo "  --clean, -c           Clean up downloaded files"
    echo "  --downloadonly, -d    Download the package only"
    echo "  --force, -f           Force installation"
    echo "  --version=<version>   Specify the version to install"
    echo "  --help                Display this help message"
    echo "  --rm, --remove        Remove the old version of yq"
}

#
#=====================main func ==============================
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root"
    exit 1
fi

#清除旧版本的影响，保证command -v命令得到正确的结果
hash -r

ARGS=$#

# Parse command line arguments
while [[ $# -gt 0 ]]
do
    key="$1"
    case $key in
    --clean|-c)
        if [[ $ARGS -eq 1 ]]; then
            clean_download
            exit 0
        fi
        AUTOCLEAN=true
        shift
        ;;
    --downloadonly|-d)
        DOWNLOAD_ONLY=true
        shift
        ;;
    --force|-f)
        FORCE=true
        shift
        ;;
    --version)
        shift
        TARGET_VERSION="${key}"
        shift
        ;;
    --version=*)
        TARGET_VERSION="${key#*=}"
        shift
        ;; 
    --help)
        print_usage
        exit 1
        ;;
    --rm|--remove)
        echo "yq components uninstall..."
        delete_old_version
        exit 1
        ;;
    -[^-]*)
        for ((i=1; i<${#key}; i++)); do
          case "${key:$i:1}" in
            f) FORCE=true ;;
            c) AUTOCLEAN=true ;;
            d) DOWNLOAD_ONLY=true ;;
            *) print_usage; exit 1 ;;
          esac
        done
        shift    
        ;;
    *)    # unknown option
        print_usage
        exit 1
        ;;
    esac
done

FORCE=${FORCE:-false}
DOWNLOAD_ONLY=${DOWNLOAD_ONLY:-false}
AUTOCLEAN=${AUTOCLEAN:-false}
TARGET_VERSION=${TARGET_VERSION:-$DEFAULT_VERSION}
BINARY_URL=$(eval echo $BINARY_URL)
TARGET_BIN=$DOWNLOAD_DIR/yq_linux_${ARCH}-${TARGET_VERSION}
echo "targetVersion=$TARGET_VERSION force=$FORCE downloadonly=$DOWNLOAD_ONLY"

if $DOWNLOAD_ONLY ; then
    download_pkg
    exit 0
fi
# Main script
if yq_needs_installation; then
    [ -n "$CURRENT_VERSION" ] && delete_old_version

    echo "Install version $TARGET_VERSION ..."
    install_yq
    $AUTOCLEAN && clean_download
fi



